﻿//using Core.Framework;
//using DotNetty.Buffers;
//using DotNetty.Codecs.Http;
//using DotNetty.Codecs.Http.WebSockets;
//using DotNetty.Framework.BaseModel;
//using DotNetty.Framework.ExtendChannelOfClient;
//using DotNetty.Transport.Channels;
//using Microsoft.AspNetCore.Http;
//using System;
//using System.Net.Http;
//using System.Threading.Tasks;

//namespace DotNetty.Framework
//{
//    /// <summary>
//    /// 负责建立通信通道
//    /// </summary>
//    public class AggregatedFullHttpRequestHandler<TMessage, THttpContext> : SimpleChannelInboundHandler<IFullHttpRequest>
//        where TMessage : AbstractMessage
//        where THttpContext : AbstractHttpContext, new()
//    {
//        protected WebSocketServerHandshaker Handshaker { get; set; }

//        IWebSocketEventTriggered<TMessage> eventTriggered;
//        IHttpEventTriggered<THttpContext> httpEventTriggered;
//        IBindChannelInfo bindChannelInfo;

//        public AggregatedFullHttpRequestHandler(
//            IWebSocketEventTriggered<TMessage> eventTriggered,
//            IHttpEventTriggered<THttpContext> httpEventTriggered,
//            IBindChannelInfo bindChannelInfo)
//        {
//            this.eventTriggered = eventTriggered;
//            this.httpEventTriggered = httpEventTriggered;
//            this.bindChannelInfo = bindChannelInfo;
//        }

//        protected async override void ChannelRead0(IChannelHandlerContext context, IFullHttpRequest request)
//        {
//            if (Common.IsShutdowned)
//            {
//                return;
//            }

//            try
//            {
//                //SendHttpResponse(context, request, new DefaultFullHttpResponse(HttpVersion.Http11, HttpResponseStatus.Forbidden));
//                if (!request.Result.IsSuccess)
//                {
//                    await context.CloseAsync();
//                    return;
//                }

//                // WebSocket
//                if (this.IsWebSocket(request.Headers))
//                {
//                    // 只是暂时测试用 后期移除
//                    var ip = GetConnectionIp(context, request.Headers);
//                    if (!string.IsNullOrWhiteSpace(ip))
//                    {
//                        string baiduKey = "0pkCx8Z3oqCuOPMz9FKSBh6QGwr7rMM5";
//                        var baiduUri = $"https://api.map.baidu.com/location/ip?ak={baiduKey}&ip={ip}&coor=bd09ll";
//                        var result = await this.GetAsync(baiduUri);
//                        if (!string.IsNullOrWhiteSpace(result))
//                        {
//                            var address = result.TryToEntity<Address>();
//                            if (address.status == 0)
//                            {
//                                LoggerUtils.Write($"ip:{ip}, address:{address?.content?.address}", "address");
//                                return;
//                            }
//                        }
//                    }
//                    await this.HandleWebSocketRequest(context, request);
//                    await this.eventTriggered.OnConnect(context);
//                }
//                // Http
//                else
//                {
//                    this.HandleHttpRequest(context, request);
//                }

//            }
//            catch (Exception ex)
//            {
//                await this.eventTriggered.OnError(context, new OnExceptionContext
//                {
//                    Action = "AggregatedFullHttpRequestHandler.ChannelRead0",
//                    Exception = ex,
//                    Message = request
//                });
//            }
//        }

//        #region 私有方法

//        private string GetConnectionIp(IChannelHandlerContext context, HttpHeaders headers)
//        {
//            try
//            {
//                headers.TryGetAsString(HttpHeaderNames.XFrameOptions, out string clientIP);
//                if (clientIP == null)
//                {
//                    var endPoint = context.Channel.RemoteAddress;
//                    System.Net.IPAddress ip = ((System.Net.IPEndPoint)endPoint).Address;
//                    clientIP = ip.ToString();
//                }
//                return clientIP;
//            }
//            catch (Exception)
//            {
//                return string.Empty;
//            }
//        }

//        public async Task<string> GetAsync(string url)
//        {
//            try
//            {
//                var result = await new HttpClient().GetAsync(url);
//                var value = await result.Content.ReadAsStringAsync();

//                if (result.StatusCode != System.Net.HttpStatusCode.OK)
//                {
//                    throw new Exception(value);
//                }

//                return value;
//            }
//            catch (Exception ex)
//            {
//                LoggerUtils.Write("GetAsync", ex);
//                return string.Empty;
//            }

//        }

//        private bool IsWebSocket(HttpHeaders headers)
//        {
//            if (headers.TryGetAsString(HttpHeaderNames.Upgrade, out string value))
//                return value.ToLower() == "websocket";

//            return false;
//        }

//        private async Task HandleWebSocketRequest(IChannelHandlerContext context, IFullHttpRequest request)
//        {
//            string host = GetWebSocketLocation(context, request);

//            var webSocketFactory = new WebSocketServerHandshakerFactory(host, null, true);

//            this.Handshaker = webSocketFactory.NewHandshaker(request);

//            if (this.Handshaker == null)
//            {
//                await WebSocketServerHandshakerFactory.SendUnsupportedVersionResponse(context.Channel);
//            }
//            else
//            {
//                await this.Handshaker.HandshakeAsync(context.Channel, request);
//            }

//            base.HandlerAdded(context);
//        }

//        private void HandleHttpRequest(IChannelHandlerContext context, IFullHttpRequest request)
//        {

//            // 构造请求上下文
//            var httpContext = new THttpContext();
//            httpContext.Host = this.GetHttpRequstHost(request);
//            httpContext.Path = request.Uri;
//            httpContext.Headers = request.Headers;
//            httpContext.Method = request.Method;
//            httpContext.ParameterByte = this.GetHttpContent(request);

//            // 调用处理器
//            try
//            {
//                // 执行前
//                this.httpEventTriggered.Before(httpContext);
//                // 执行任务
//                var task = this.httpEventTriggered.ActionAsync(httpContext);

//                Task.WhenAll(task).ContinueWith(t =>
//                {
//                    // 执行后
//                    this.httpEventTriggered.After(httpContext);

//                    // 构造Response
//                    var response = new DefaultFullHttpResponse(HttpVersion.Http11, httpContext.ResponseStatus);
//                    // 写入Header信息
//                    foreach (var item in httpContext.ResponseHeader)
//                        response.Headers.Set(item.Key, item.Value);
//                    // 写入响应信息
//                    IByteBuffer buffer = Unpooled.CopiedBuffer(httpContext.ResponseBody ?? "", httpContext.ResponseEncoding);
//                    response.Content.WriteBytes(buffer);
//                    if (buffer.ReferenceCount > 0)
//                    {
//                        buffer.Release();
//                    }
//                    HttpUtil.SetContentLength(response, response.Content.ReadableBytes);

//                    // 推送消息到客户端
//                    Task flusTask = context.Channel.WriteAndFlushAsync(response);

//                    // 推送成功后关闭连接
//                    flusTask
//                        .ContinueWith(
//                            (tt, channel) => ((IChannelHandlerContext)channel).CloseAsync(),
//                            context,
//                            TaskContinuationOptions.ExecuteSynchronously);

//                });

//            }
//            catch (Exception exception)
//            {
//                // 发生异常
//                this.httpEventTriggered.Error(httpContext, exception);
//            }
//        }


//        private string GetWebSocketLocation(IChannelHandlerContext context, IFullHttpRequest request)
//        {

//            string location = this.GetHttpRequstHost(request);

//            if (string.IsNullOrWhiteSpace(location))
//                throw new Exception("host is null");

//            // 用户身份
//            string token = this.GetHttpRequstToken(request);
//            if (!string.IsNullOrWhiteSpace(token))
//            {
//                try
//                {
//                    var task = this.bindChannelInfo.BindAsync(context, token);
//                    Task.WhenAll(task);
//                }
//                catch
//                {
//                    context.CloseAsync();
//                }
//            }

//            //context.BindHost(location.Split(':')[0]);

//            return "ws://" + location;

//        }

//        private string GetHttpRequstHost(IFullHttpRequest request)
//        {
//            bool isHavHost = request.Headers.TryGetAsString(HttpHeaderNames.Host, out string value);
//            return isHavHost ? value : string.Empty;
//        }

//        private string GetHttpRequstToken(IFullHttpRequest request)
//        {
//            string uri = request.Uri.ToString();
//            var uriArr = uri.Split('?');
//            if (uriArr.Length > 1)
//            {
//                LoggerUtils.Write($"GetHttpRequstToken:{uriArr[1]},uri:{uri}");

//                return uriArr[1];
//            }
//            else
//            {
//                return string.Empty;
//            }
//        }

//        private byte[] GetHttpContent(IFullHttpRequest request)
//        {
//            byte[] req = new byte[request.Content.ReadableBytes];
//            request.Content.ReadBytes(req);
//            return req;
//        }

//        #endregion
//    }


//    class Address
//    {
//        public int status { get; set; }
//        public AddressContent content { get; set; }
//    }

//    class AddressContent
//    {
//        public string address { get; set; }
//        public AddressDetail address_detail { get; set; }
//    }

//    class AddressDetail
//    {
//        public string city { get; set; }
//        public string province { get; set; }
//    }
//}
